package gui.jtab.pistilo;

import event.notifyTexture.EventNotifyTexture;
import event.notifyTexture.NotifyTexture;
import figuras.PuntoVector;
import gui.GLJPanels.GLJPanelNW;
import gui.GLJPanels.GLJPanelPistilo;
import gui.GLListeners.GLListenerCurvas;
import gui.GLListeners.GLListenerPistilo;
import gui.GLListeners.GLListenerVisor;
import gui.jtab.JTab;
import gui.jtab.common.JTabTextureOptions;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Observable;

import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JTabbedPane;

import properties.Config;
import utils.files.FileManager;
import utils.files.FileManagerFlowers;
import camaras.Camara;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import constantes.Consts;

public class JTabObjectPistilo extends JTab {

	private static final long serialVersionUID = 1L;

	protected JTabbedPane tabOptionsPanel;

	protected boolean updated;

	public JTabObjectPistilo() {
		setName("pistil");
		updated = false;
		// inicializamos las componentes visuales
		initComponents();

		PuntoVector eye;
		PuntoVector look;
		PuntoVector up;
		Config config;
		try {
			config = Config.getInstance();
			String eyeProperties = config.getString("pistilo.visor1.eye");
			String lookProperties = config.getString("pistilo.visor1.look");
			String upProperties = config.getString("pistilo.visor1.up");
			String[] coordEye = eyeProperties.split(" ");
			String[] coordLook = lookProperties.split(" ");
			String[] coordUp = upProperties.split(" ");
			eye = new PuntoVector(Integer.parseInt(coordEye[0]), Integer
					.parseInt(coordEye[1]), Integer.parseInt(coordEye[2]), 1);
			look = new PuntoVector(Integer.parseInt(coordLook[0]), Integer
					.parseInt(coordLook[1]), Integer.parseInt(coordLook[2]), 1);
			up = new PuntoVector(Integer.parseInt(coordUp[0]), Integer
					.parseInt(coordUp[1]), Integer.parseInt(coordUp[2]), 1);
			GLLVisor1 = new GLListenerVisor(eye, look, up,
					Consts.XRIGHT_GLL_PISTILO, Consts.YTOP_GLL_PISTILO);

			eyeProperties = config.getString("pistilo.visor2.eye");
			lookProperties = config.getString("pistilo.visor2.look");
			upProperties = config.getString("pistilo.visor2.up");
			coordEye = eyeProperties.split(" ");
			coordLook = lookProperties.split(" ");
			coordUp = upProperties.split(" ");
			eye = new PuntoVector(Integer.parseInt(coordEye[0]), Integer
					.parseInt(coordEye[1]), Integer.parseInt(coordEye[2]), 1);
			look = new PuntoVector(Integer.parseInt(coordLook[0]), Integer
					.parseInt(coordLook[1]), Integer.parseInt(coordLook[2]), 1);
			up = new PuntoVector(Integer.parseInt(coordUp[0]), Integer
					.parseInt(coordUp[1]), Integer.parseInt(coordUp[2]), 1);
			GLLVisor2 = new GLListenerVisor(eye, look, up,
					Consts.XRIGHT_GLL_PISTILO, Consts.YTOP_GLL_PISTILO);
			
			eyeProperties = config.getString("pistilo.visor3.eye");
			lookProperties = config.getString("pistilo.visor3.look");
			upProperties = config.getString("pistilo.visor3.up");
			coordEye = eyeProperties.split(" ");
			coordLook = lookProperties.split(" ");
			coordUp = upProperties.split(" ");
			eye = new PuntoVector(Integer.parseInt(coordEye[0]), Integer
					.parseInt(coordEye[1]), Integer.parseInt(coordEye[2]), 1);
			look = new PuntoVector(Integer.parseInt(coordLook[0]), Integer
					.parseInt(coordLook[1]), Integer.parseInt(coordLook[2]), 1);
			up = new PuntoVector(Integer.parseInt(coordUp[0]), Integer
					.parseInt(coordUp[1]), Integer.parseInt(coordUp[2]), 1);
			GLLVisor3 = new GLListenerVisor(eye, look, up,
					Consts.XRIGHT_GLL_PISTILO, Consts.YTOP_GLL_PISTILO);

			visor1.addGLEventListener(GLLVisor1);
			visor2.addGLEventListener(GLLVisor2);
			visor3.addGLEventListener(GLLVisor3);

			// asignamos los eventos a las componentes visuales

			// GLL.addObserver(visor1);
			// GLL.addObserver(visor2);
			// GLL.addObserver(visor3);
			GLL.addObserver(this);

			canvas.setFocusable(true);

			NotifyTexture notifyTextureManager = new NotifyTexture();
			notifyTextureManager.addEventNotifyTextureListener(this);

			((JTabTextureOptions) texturePanel)
					.addNotifyTexture(notifyTextureManager);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void initComponents() {
		java.awt.GridBagConstraints gridBagConstraints;

		visor1 = new GLJPanelNW();
		visor2 = new GLJPanelNW();
		visor3 = new GLJPanelNW();
		GLL = new GLListenerPistilo();
		canvas = new GLJPanelPistilo((GLListenerPistilo) GLL);
		canvas.addGLEventListener(GLL);
		// dentationPanel = new JTabDentationOptions();
		texturePanel = new JTabTextureOptions(Consts.TEXTURE_PISTILS_FOLDER,
				canvas);

		visor1.setBorder(new javax.swing.border.SoftBevelBorder(
				javax.swing.border.BevelBorder.RAISED));
		visor2.setBorder(new javax.swing.border.SoftBevelBorder(
				javax.swing.border.BevelBorder.RAISED));
		visor3.setBorder(new javax.swing.border.SoftBevelBorder(
				javax.swing.border.BevelBorder.RAISED));
		canvas.setBorder(new javax.swing.border.SoftBevelBorder(
				javax.swing.border.BevelBorder.RAISED));

		setLayout(new java.awt.GridBagLayout());

		javax.swing.GroupLayout panel1Layout = new javax.swing.GroupLayout(
				visor1);
		visor1.setLayout(panel1Layout);
		panel1Layout.setHorizontalGroup(panel1Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 200,
				Short.MAX_VALUE));
		panel1Layout.setVerticalGroup(panel1Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 200,
				Short.MAX_VALUE));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 2;
		gridBagConstraints.ipady = 2;
		gridBagConstraints.weightx = 200.0;
		gridBagConstraints.weighty = 200.0;
		add(visor1, gridBagConstraints);

		javax.swing.GroupLayout panel2Layout = new javax.swing.GroupLayout(
				visor2);
		visor2.setLayout(panel2Layout);
		panel2Layout.setHorizontalGroup(panel2Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 200,
				Short.MAX_VALUE));
		panel2Layout.setVerticalGroup(panel2Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 200,
				Short.MAX_VALUE));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 2;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 2;
		gridBagConstraints.ipady = 2;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 200.0;
		gridBagConstraints.weighty = 200.0;
		add(visor2, gridBagConstraints);

		javax.swing.GroupLayout panel3Layout = new javax.swing.GroupLayout(
				visor3);
		visor3.setLayout(panel3Layout);
		panel3Layout.setHorizontalGroup(panel3Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 200,
				Short.MAX_VALUE));
		panel3Layout.setVerticalGroup(panel3Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 200,
				Short.MAX_VALUE));

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridy = 1;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 2;
		gridBagConstraints.ipady = 2;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
		gridBagConstraints.weightx = 200.0;
		gridBagConstraints.weighty = 200.0;
		add(visor3, gridBagConstraints);

		javax.swing.GroupLayout panel4Layout = new javax.swing.GroupLayout(
				canvas);
		canvas.setLayout(panel4Layout);
		panel4Layout.setHorizontalGroup(panel4Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 600,
				Short.MAX_VALUE));
		panel4Layout.setVerticalGroup(panel4Layout.createParallelGroup(
				javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 600,
				Short.MAX_VALUE));

		canvas.setBounds(0, 0, 600, 600);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 1;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.gridheight = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 6;
		gridBagConstraints.ipady = 6;
		gridBagConstraints.weightx = 600.0;
		gridBagConstraints.weighty = 600.0;
		add(canvas, gridBagConstraints);

		gridBagConstraints = new java.awt.GridBagConstraints();
		gridBagConstraints.gridx = 2;
		gridBagConstraints.gridy = 0;
		gridBagConstraints.gridheight = 3;
		gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
		gridBagConstraints.ipadx = 1;
		gridBagConstraints.ipady = 6;
		gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
		gridBagConstraints.weightx = 100.0;
		gridBagConstraints.weighty = 600.0;
		tabOptionsPanel = new JTabbedPane();
		tabOptionsPanel.addTab("Texturas", texturePanel);
		add(tabOptionsPanel, gridBagConstraints);
	}

	public void abrir(File file) {
		String pistil = file.getAbsolutePath();
		pistil = FileManagerFlowers.setPistil(pistil);
		pistil = pistil
				+ file.getName().substring(0, file.getName().indexOf("."));
		canvas.getContext().makeCurrent();
		((GLListenerPistilo) GLL).limpiaCurvas();
		((GLListenerPistilo) GLL).cargaPistilo(new File(pistil));
		// File textura = new File(pistil+".jpg");
		// if(textura.exists()){
		// ((GLListenerPistilo) GLL).setTexture(textura.getPath());
		//
		// }
		cargarTextura(pistil);
		canvas.repaint();
		canvas.requestFocus();

		enabledMenuGuardar = true;
		updated = false;
	}

	public void capturaPantalla(String path) {
		try {
			Dimension size = canvas.getSize();
			BufferedImage myImage = new BufferedImage(size.width, size.height,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D g2 = myImage.createGraphics();
			canvas.paint(g2);
			OutputStream out = new FileOutputStream(path);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(myImage);
			out.close();
		} catch (HeadlessException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ImageFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void guardar() {
		// Dimension size = canvas.getSize();
		// BufferedImage myImage = new BufferedImage(size.width, size.height,
		// BufferedImage.TYPE_INT_RGB);
		// Graphics2D g2 = myImage.createGraphics();
		// String filePath = Consts.PISTILOS_FOLDER+"/pistilo.jpg";
		// canvas.paint(g2);
		// try {
		// OutputStream out = new FileOutputStream(filePath);
		// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		// encoder.encode(myImage);
		// out.close();
		// } catch (Exception e) {
		// System.out.println(e);
		// }
		// ProcesadorImagenes pro = new ProcesadorImagenes();
		// try {
		// BufferedImage image = pro.escalarATamanyo(new File(filePath), 100,
		// 100, "jpg");
		// pro.salvarImagen(image, Consts.PISTILOS_FOLDER
		// + "/pistilo_mini.jpg", "jpg");
		// } catch (IOException e) {
		// e.printStackTrace();
		// }

		String pistil = FileManagerFlowers.getPistil();
		guardarComo(new File(pistil.substring(0, pistil.lastIndexOf("."))));
		makeCurrentContext();
		// canvas.getContext().makeCurrent();
		// ((GLListenerCurvarHoja) GLL).save(Consts.DIRECTORY_FILE_HOJA);
		// canvas.repaint();
		// canvas.requestFocus();

	}

	// public void guardarComo(File file) {
	// ((GLListenerPistilo)GLL).guardaPistilo(file);
	// //canvas.repaint();
	// canvas.requestFocus();
	//
	// }

	public void guardarPlyAscii(String path) {
		JFileChooser fc = new JFileChooser();
		int returnVal = fc.showSaveDialog(null);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			((GLListenerPistilo) GLL).saveToAsciiPLY(file.getAbsolutePath());
		}
		canvas.requestFocus();
	}

	public void guardarPlyBinary(String path) {
		JFileChooser fc = new JFileChooser();
		int returnVal = fc.showSaveDialog(null);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();
			((GLListenerPistilo) GLL).saveToBinaryPLY(file.getAbsolutePath());
		}
		canvas.requestFocus();

	}

	public void makeCurrentContext() {
		canvas.display();
		canvas.getContext().makeCurrent();
		canvas.repaint();
		visor1.repaint();
		visor2.repaint();
		visor3.repaint();
		canvas.repaint();
		canvas.requestFocus();
	}

	public void nuevo() {
		enabledMenuGuardar = false;
		FileManagerFlowers.setPistil(null);
		canvas.getContext().makeCurrent();
		((GLListenerCurvas) GLL).limpiaCurvas();
		canvas.repaint();
		canvas.requestFocus();
		GLLVisor1.setComponente(null);
		GLLVisor2.setComponente(null);
		GLLVisor3.setComponente(null);
		this.setPosicionCamara(Camara.FRONTAL);
		// visor1.repaint();
		// visor2.repaint();
		// visor3.repaint();

	}

	public void setFormatoDibujo(int glOption) {
		canvas.getContext().makeCurrent();
		((GLListenerCurvas) GLL).setGLOption(glOption);
		canvas.repaint();
		canvas.requestFocus();
	}

	public void setPosicionCamara(int position) {
		canvas.getContext().makeCurrent();
		((GLListenerCurvas) GLL).setCamaraPosicion(position);
		canvas.repaint();
		canvas.requestFocus();
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		if (!updated) {
			GLLVisor1.setComponente(GLL.getComponente());
			GLLVisor2.setComponente(GLL.getComponente());
			GLLVisor3.setComponente(GLL.getComponente());
			updated = true;
		}
		visor1.repaint();
		visor2.repaint();
		visor3.repaint();
		canvas.requestFocus();
	}

	public void catchNotifyTextureListener(EventNotifyTexture evt) {
		makeCurrentContext();
	}

	public void reset() {
		canvas.getContext().makeCurrent();
		((GLListenerPistilo) GLL).reset();
		canvas.repaint();
		canvas.requestFocus();
		//        
		// visor1.repaint();
		// visor2.repaint();
		// visor3.repaint();
	}

	public void setColor() {
		canvas.getContext().makeCurrent();
		Color newColor = JColorChooser.showDialog(null, "Elija un color",
				Color.GREEN);
		if (newColor != null) {
			((GLListenerPistilo) GLL).setColor(newColor);
		}
		canvas.repaint();
		canvas.requestFocus();
	}

	public void perfila() {
		canvas.getContext().makeCurrent();
		((GLListenerPistilo) GLL).revolucion();
		canvas.repaint();
		canvas.requestFocus();
		updated = false;
	}

	public void resetea() {
		canvas.getContext().makeCurrent();
		((GLListenerPistilo) GLL).reset();
		canvas.repaint();
		canvas.requestFocus();

	}

	@Override
	public void almacenaEnGaleria(File file) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		String name = Consts.SAVE_PISTILS_FOLDER + format.format(new Date());
		File directory = new File(name);
		guardarComo(directory);
		directory.mkdir();
		FileManager.unZipComponent(name + ".flw", name + "/");
		makeCurrentContext();
	}

}
